'''百度飞桨Hello, paddle!
Author: Fei Zhao
'''
# 传统程序：给定规则和输入，计算得到输出
# 机器学习程序：给定输入和样本，自动学习规则，然后利用学习到的规则计算得到输出

import paddle
import numpy as np

print('paddle ' + paddle.__version__)

# 输出y和输入x具有线性关系：y=2*x+5
# 下面使用飞桨搭建一个线性模型学习出w, b的值
w, b = 2, 5
# x中的每一行是一个样本
x = paddle.to_tensor([[1.], [4.], [5.], [9.], [8.], [10.], [12.]])
y = x * w + b

# 开始学习前的参数值
model = paddle.nn.Linear(in_features=1, out_features=1)
w_before_opt = model.weight.numpy().item()
b_before_opt = model.bias.numpy().item()
print("初始化w的值: {}".format(w_before_opt))
print("初始化b的值: {}".format(b_before_opt))

# 定义损失函数与优化方法，开始训练
mse_loss = paddle.nn.MSELoss()
sgd_optimizer = paddle.optimizer.SGD(learning_rate=0.01, parameters = model.parameters())
total_epoch = 12000
for i in range(total_epoch):
    y_predict = model(x)
    loss = mse_loss(y_predict, y)
    loss.backward()
    sgd_optimizer.step()
    sgd_optimizer.clear_grad()
    if i%1000 == 0:
        print("epoch {} loss {}".format(i, loss.numpy()))

print("finished training， loss {}".format(loss.numpy()))

# 查看训练得到的参数
w_after_opt = model.weight.numpy().item()
b_after_opt = model.bias.numpy().item()

print("学习到w的值: {}".format(w_after_opt))
print("学习到b的值: {}".format(b_after_opt))
print("Hello, paddle!")